
#ifndef		FITTED_VI_SOLVER
#define		FITTED_VI_SOLVER

#include "KDTree.h"
#include "MDPSolver.h"
#include <list>
using namespace std; 

class KDTreeLearner; 


class FittedVISolver
	:public MDPSolver
{
public: 
	FittedVISolver(MREAgent* a, TFGenerator* tf, RFGeneralizer* rf); 
	~FittedVISolver(); 
	void generateUniformSamples(list< std::pair<Observation,double> >& l, int sampleSize);

	virtual Action getBestAction(Observation state);
	virtual void	solveModel(Observation currentState); 
	virtual double getStateValue(const Observation state){ return getStateValue(state,0); } 
	virtual void operator()(); 

	double getStateValue(const Observation state, int horizon);		//returns the value of a state
	double getQValue(Observation state, Action a, int horizon=1);	//returns the qvalue (it considers this: q(s,a) = \gamma* V(T(s,a))

protected:
	Observation getNextItem(Observation st, int n);
	void clearSamples(); 
public:

	KDTreeLearner* kdGens;		//this is the casted version of tfGens (fitted VI only works with KDTree for now)
	kdtree::KDTree*		tree;			//this is the KDTree we store the value function 
	list<KData> samples; 
};


class FittedVIMetric: public FittedVISolver
{
	FittedVIMetric(MREAgent* a, TFGenerator* tf, RFGeneralizer* rf); 



};

#endif
